package indi.simple.pms.config;

import com.zaxxer.hikari.HikariDataSource;
import indi.simple.pms.aop.datasource.DataSourceType;
import indi.simple.pms.aop.datasource.DynamicDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 类
 *
 * @author wanglunhui
 * @since 2022-04-19 17:54:29
 */
@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSourceProperties masterDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.slave", name = "enable", havingValue = "true")
    public DataSourceProperties slaveDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Bean(name = "masterDataSource")
    @ConfigurationProperties("spring.datasource.master.hikari")
    public DataSource masterDataSource(DataSourceProperties masterDataSourceProperties) {
        HikariDataSource dataSource = (HikariDataSource)masterDataSourceProperties.initializeDataSourceBuilder().type(masterDataSourceProperties.getType()).build();

        if (StringUtils.hasText(masterDataSourceProperties.getName())) {
            dataSource.setPoolName(masterDataSourceProperties.getName());
        }

        return dataSource;
    }

    @Bean(name = "slaveDataSource")
    @ConfigurationProperties("spring.datasource.slave.hikari")
    @ConditionalOnProperty(prefix = "spring.datasource.slave", name = "enable", havingValue = "true")
    public DataSource slaveDataSource(DataSourceProperties slaveDataSourceProperties) {
        HikariDataSource dataSource = (HikariDataSource)slaveDataSourceProperties.initializeDataSourceBuilder().type(slaveDataSourceProperties.getType()).build();

        if (StringUtils.hasText(slaveDataSourceProperties.getName())) {
            dataSource.setPoolName(slaveDataSourceProperties.getName());
        }

        return dataSource;
    }

    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource, DataSource localDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource);
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }

}
